package com.vcaresolution.util;

import java.io.Serializable;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;
import org.hibernate.criterion.SimpleExpression;
import org.springframework.beans.BeanUtils;

import com.vcaresolution.logistic.util.ApplicationConstants;

/**
 * This <code>Utils</code> class has all utility methods used across
 * various web applications.
 * 
 * @author Snehal Shah
 * @version 1.0
 */
public final class Utils {
	private Utils(){}
	
	/**
	 * This method is used to get string representation of a Object
	 * passed as an argument
	 * 
	 * @param object
	 * @return
	 */
	public static final String toString(Object object){
		return ToStringBuilder.reflectionToString(object,ToStringStyle.MULTI_LINE_STYLE);
	}
	
	/**
	 * This method returns current date representation
	 * @return
	 */
	public static synchronized final Date getCurrentDate(){
		return new Date(System.currentTimeMillis());
	}
	
	/**
	 * @param param
	 * @return
	 */
	public static boolean isEmpty(final String param) {
		final boolean error = false;
		if (param == null || param.trim().length() <= 0) {
			return true;
		}
		return error;
	}

	/**
	 * @param param
	 * @return
	 */
	public static boolean isValidAlphabet(final String param) {
		boolean error = false;
		if (!Utils.isEmpty(param)) {
			final String a = "^[a-zA-Z]+$";
			final Pattern p = Pattern.compile(a);
			final Matcher m = p.matcher(param);
			error = m.find();
		}
		return error;
	}
	
	/**#editedByVishal*/
	/**
	 * @objective -: to copy properties from one bean list to another.
	 * @date -: 09/13/2013
	 * @version -: 1.0
	 * @since -: ShipSoft 1.0
	 * @author -: Vishal
	 * */
	public static <T> List<T> copyProperties(List<? extends Object> list,Class<T> classObject) 
	{
		try
		{
			List<T> returnList = new ArrayList<T>();
			T instance;
			for(Object object : list)
			{
				instance = (T)classObject.newInstance();
				BeanUtils.copyProperties(object, instance);
				returnList.add(instance);
			}
			return returnList;
		}
		catch (Exception e) 
		{
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * @param param
	 * @return
	 */
	public static boolean isValidDigit(final String param) {
		final String regxPattern = "^[0-9]+$";
		final Pattern pattern = Pattern.compile(regxPattern);
		final Matcher matcher = pattern.matcher(param);
		return matcher.matches();
	}

	/**
	 * @param param
	 * @return
	 */
	public static boolean isValidDate(final String param) {
		final String regxPattern = "(0?[1-9]|[12][0-9]|3[01])/(0?[1-9]|1[012])/((19|20)\\d\\d)";
		final Pattern pattern = Pattern.compile(regxPattern);
		final Matcher matcher = pattern.matcher(param);
		if (matcher.matches()) {
			matcher.reset();
			if (matcher.find()) {
				final String day = matcher.group(1);
				final String month = matcher.group(2);
				final int year = Integer.parseInt(matcher.group(3));

				if (day.equals("31") && (month.equals("4") || month.equals("6") || month.equals("9") || month.equals("11") || month.equals("04")
								|| month.equals("06") || month.equals("09"))) {
					return false; // only 1,3,5,7,8,10,12 has 31 days
				} else if (month.equals("2") || month.equals("02")) {
					// leap year
					if (year % 4 == 0) {
						if (day.equals("30") || day.equals("31")) {
							return false;
						} else {
							return true;
						}
					} else {
						if (day.equals("29") || day.equals("30") || day.equals("31")) {
							return false;
						} else {
							return true;
						}
					}
				} else {
					return true;
				}
			} else {
				return false;
			}
		} else {
			return false;
		}
	}

	/**
	 * @param param
	 * @return
	 */
	public static boolean isValidEmail(final String param) {
		boolean error = false;
		final String a = "^(?:\\w+\\.?)*\\w+@(?:\\w+\\.?)*\\w+$";
		final Pattern p = Pattern.compile(a);
		final Matcher m = p.matcher(param);
		error = m.find();
		return error;
	}

	/**
	 * @param param
	 * @return
	 */
	public static boolean isValidTimeStamp(final String param) {
		final String regxPattern = "([01]?[0-9]|2[0-3]):[0-5][0-9]";
		final Pattern pattern = Pattern.compile(regxPattern);
		final Matcher matcher = pattern.matcher(param);
		return matcher.matches();
	}
	
	/**
	 * This method converts java.util.Date into dd/MM/yyyy format
	 * @param date
	 * @return String
	 */
	public static String convertDateObjectToDDMMYYYY(final Date date) {
		String formattedDate = null;

		if (date != null) {
			formattedDate = ApplicationConstants.DEFAULT_DDMMYYYY_DATE_FORMAT.format(date);
		}//end of if

		return formattedDate;
	}
	
	/**
	 * @param param
	 * @return
	 */
	public static boolean isEmptyInteger(final Integer param) {
		final boolean error = false;
		if (param == null || param.intValue() <= 0) {
			return true;
		}
		return error;
	}
	
	public static List<SimpleExpression> getEqExpressionList(String field, Serializable fieldValue){
		List<SimpleExpression> expressionList = new ArrayList<SimpleExpression>();
		expressionList.add(Restrictions.eq(field, fieldValue));
		
		return expressionList;
	}
	
	public static List<SimpleExpression> getLikeExpressionList(String field, String fieldValue){
		List<SimpleExpression> expressionList = new ArrayList<SimpleExpression>();
		expressionList.add(Restrictions.like(field, fieldValue, MatchMode.ANYWHERE));
		
		return expressionList;
	}
	
	/**
	 * This method responsible to get Tokens.
	 * @param str
	 * @param delemenString
	 * @param trimmed
	 * @return
	 */
	public static String[] getTokens(String str, String delemenString, boolean trimmed){
		
		StringTokenizer st = new StringTokenizer(str,delemenString);
		String[] tokenArray = null;
		
		ArrayList<String> tokenList = new ArrayList<String>();
		String tokenValue = null;		
		
		while(st.hasMoreTokens())
		{
			if(trimmed)
				tokenValue = st.nextToken().trim();
			else
				tokenValue = st.nextToken();
			
			if(tokenValue != null && tokenValue.length() > 0 )
			{
				tokenList.add(tokenValue);
			}			
		}
		
		if( tokenList.size() > 0 )
		{
			tokenArray = new String[tokenList.size()];
			for(int i=0;i<tokenList.size();i++)
			{
				tokenArray[i] = tokenList.get(i);
			}
		}
		else
		{
			tokenArray = new String[]{};
		}
		
		return tokenArray;
	}
	
	/**
	 * This method responsible to get Time.
	 * @param strHHMMAMPMTime
	 * @return
	 * @throws ParseException
	 */
	public static Calendar getTime(String strHHMMAMPMTime) throws ParseException{
		
		Calendar cal = Calendar.getInstance();
		cal.setTime(ApplicationConstants.DEFAULT_TIME_STAMP_FORMAT.parse(strHHMMAMPMTime));
		return cal;
	}
}
